# -*- encoding: utf-8 -*-
"""
App级的共通的检测类的装饰器
"""

import hmac
import hashlib
import base64
import copy
import urllib
from functools import wraps

from tornado import gen
from common import utiltool, timetool
from common import config as conf
import settings

def check_sign(fn):
    """
    签名验证
    :param fn:
    :return:
    """
    def _check_sign(request_handler):
        if not settings.IS_CHECK_SIGN:
            return fn(request_handler)
        else:
            dicx = copy.deepcopy(request_handler.request.arguments)
            sign = dicx.pop('sign', None)
            sign = sign[0] if sign else ''
            try:
                # 把不参与签名的key移除
                for key in settings.IGNORE_SIGN_KEY_LIST:
                    dicx.pop(key, None)
            except KeyError:
                pass
            try:
                public_key = settings.PUBLIC_KEY
            except KeyError:
                public_key = ''
            dict = sorted(dicx.iteritems(), key=lambda d: d[0])
            canshu = ""
            for (k, v) in dict:
                v_len = len(v)
                for i in range(v_len):
                    canshu += '{0}{1}'.format(k, v[i])
            canshu = canshu[0:canshu.__len__()]
            signer = hmac.new(public_key, canshu, hashlib.sha1).digest()

            if sign == base64.b64encode(signer):
                return fn(request_handler)
            else:
                return utiltool.response_write(request_handler, {"code": "1001", "msg": conf.CODE1001})
    return _check_sign


def check_sign_for_pay(fn):
    """
    农业项目中调用支付签名验证
    :param fn:
    :return:
    """
    def _check_sign(request_handler):
        if not settings.IS_CHECK_SIGN:
            return fn(request_handler)
        else:
            dicx = copy.deepcopy(request_handler.request.arguments)
            sign = dicx.pop('sign', None)
            sign = sign[0] if sign else ''
            try:
                # 把不参与签名的key移除
                for key in settings.IGNORE_SIGN_KEY_LIST:
                    dicx.pop(key)
            except KeyError:
                pass
            try:
                public_key = settings.PAY_PUBLIC_KEY
            except KeyError:
                public_key = ''
            dict = sorted(dicx.iteritems(), key=lambda d: d[0])
            canshu = ""
            for (k, v) in dict:
                v_len = len(v)
                for i in range(v_len):
                    canshu += '{0}{1}'.format(k, v[i])
            canshu = canshu[0:canshu.__len__()]
            signer = hmac.new(public_key, canshu, hashlib.sha1).digest()
            if sign == base64.b64encode(signer):
                return fn(request_handler)
            else:
                return utiltool.response_write(request_handler, {"code": "1001", "msg": conf.CODE1001})
    return _check_sign


def check_access_token(func):
    """
    检测用户本次的access_token是否有效
    :param request_handler: request对象请求
    :return:{'code':'','msg':''}
    """
    @wraps(func)
    @gen.coroutine
    def check(*args, **kw):
        """
        """
        para_dict = args[0].request.arguments
        user_id = para_dict['user_id'][0]
        try:
            user_id = int(user_id)
        except ValueError:
            user_id = 0
        access_token = para_dict['access_token'][0]
        product_type = int(para_dict['product_type'][0])

        collection = mongo_mtd_pool.get_collection(settings.MONGO_DATA_DB, settings.MONGO_DEVICE_COLLECTION)
        result = yield collection.find_one(
            {'userid': user_id, 'accesstoken': access_token, 'producttype': product_type},
            {'_id': 0, 'ExpireDate': 1})
        if result:
            # if result['ExpireDate'] >= timetool.get_timestamp():
            if True:
                yield func(*args)
            else:
                if user_id in settings.WHITE_USER_ID_LIST:
                    yield func(*args)
                else:
                    utiltool.response_write(args[0], {"code": "1011", "msg": conf.CODE1011})
        else:
            if user_id in settings.WHITE_USER_ID_LIST:
                yield func(*args)
            else:
                utiltool.response_write(args[0], {"code": "1011",
                                                  "msg": conf.CODE1011})
    return check


def generate_sign(public_key, para_dict):
    """
    根据指定的参数及公钥生成签名
    :param public_key:公钥
    :param para_dict:参数
    :return:[base64.b64encode(signer),quote(base64.b64encode(signer))]
    """
    dict = sorted(para_dict.iteritems(), key=lambda d:d[0])
    canshu = ""
    for (k, v) in dict:
        canshu += '{0}{1}'.format(k, str(v))
    canshu = canshu[0:canshu.__len__()]
    signer = hmac.new(public_key, canshu, hashlib.sha1).digest()
    res = base64.b64encode(signer)
    res_encoded = urllib.quote(res)
    return [res, res_encoded]



def check_login_for_price(func):
    """
    检测用户本次的access_token是否有效
    :param request_handler: request对象请求
    :return:{'code':'','msg':''}
    """
    @wraps(func)
    @gen.coroutine
    def check(*args, **kw):
        list_args = list(args)
        request_handler = list_args.pop(0)

        para_dict = request_handler.request.arguments
        user_id = para_dict['user_id'][0]
        try:
            user_id = int(user_id)
        except ValueError:
            user_id = 0
        access_token = para_dict['access_token'][0]
        product_type = int(para_dict['product_type'][0])

        collection = mongo_mtd_pool.get_collection(
            settings.MONGO_DATA_DB, settings.MONGO_DEVICE_COLLECTION)
        result = yield collection.find_one(
            {'userid': user_id, 'accesstoken': access_token, 'producttype': product_type},
            {'_id': 0, 'ExpireDate': 1})
        if result:
            request_handler.verified = True
        else:
            request_handler.verified = False
        list_args.insert(0, request_handler)
        yield func(*list_args)
    return check
